# :nocov:
begin
  require "phantomjs"
rescue LoadError
  # if we can't load phantomjs, assume the cli is installed and in the path
end
# :nocov:

require "teaspoon/driver/base"

module Teaspoon
  module Driver
    class Phantomjs < Base
      include Teaspoon::Utility

      def initialize(options = nil)
        options ||= []
        case options
        when Array then @options = options
        when String then @options = options.split(" ")
        when Hash then @options = options.map { |k, v| "--#{k}=#{v}" }
        else raise Teaspoon::DriverOptionsError.new(types: "string, array or hash")
        end
      end

      def run_specs(runner, url)
        run(*driver_options(url)) do |line|
          runner.process(line) if line && line.strip != ""
        end
      end

      protected

      def run(*args, &block)
        IO.popen([executable, *args].join(" ")) { |io| io.each(&block) }

        unless $?.nil? || $?.success?
          raise Teaspoon::DependencyError.new("Failed to use phantomjs, which exited with status code: #{$?.exitstatus}")
        end
      end

      def driver_options(url)
        [
          @options,
          escape_quotes(script),
          escape_quotes(url),
          Teaspoon.configuration.driver_timeout
        ].flatten.compact
      end

      def escape_quotes(string)
        %{"#{string.gsub('"', '\"')}"}
      end

      def executable
        return @executable if @executable
        @executable = defined?(::Phantomjs) ? ::Phantomjs.path : which("phantomjs")
        return @executable unless @executable.blank?
        raise Teaspoon::MissingDependencyError.new("Unable to locate phantomjs. Install it or use the phantomjs gem.")
      end

      def script
        File.expand_path("../phantomjs/runner.js", __FILE__)
      end
    end
  end
end
